<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/3/12 0012
 * Time: 21:19
 */
// socket 服务端代码
set_time_limit(0);
$address = '0.0.0.0';
$port = 9800;
/**
 * * 创建一个SOCKET
 * AF_INET=是ipv4 如果用ipv6，则参数为 AF_INET6
 * SOCK_STREAM为socket的tcp类型，如果是UDP则使用SOCK_DGRAM
 */
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die('socket_create 失败原因是 ' . socket_strerror(socket_last_error()) . "\n");

//设置非阻塞
socket_set_block($sock) or die('socket_set_block 失败原因是' . socket_strerror(socket_last_error()) . "\n"); //返回true/false

//绑定到socket端口
$result = socket_bind($sock, $address, $port) or die('socket_bind 失败原因是' . socket_strerror(socket_last_error()) . "\n"); //成功时返回 TRUE， 或者在失败时返回 FALSE。

//开始监听

$result = socket_listen($sock, 4) or die('socket_listen 失败原因是' . socket_strerror(socket_last_error()) . "\n"); //成功时返回 TRUE， 或者在失败时返回 FALSE。

echo "OK\nBinding the socket on $address:$port ... ";
echo "OK\nNow ready to accept connections.\nListening on the socket ... \n";

do {
    //它接收连接请求并调用一个子连接Socket来处理客户端和服务器间的信息
    $msgSocket = socket_accept($sock) or die('socket_accept 失败原因是' . socket_strerror(socket_last_error()) . "\n");//成功时返回新的套接字资源，错误时返回False。可以通过调用

    //读取客户端数据
    //socket_read函数会一直读取客户端数据,直到遇见\n,\t或者\0字符.PHP脚本把这写字符看做是输入的结束符
    $buffer = socket_read($msgSocket, 1024);
    echo '接收到客户端数据:' . $buffer;
    ////数据传送 向客户端写入返回结果
    $msg = "连接成功\n";
    socket_write($msgSocket, $msg, strlen($msg)) or die('socket_write 失败原因是' . socket_strerror(socket_last_error()) . "\n");
    //一旦输出被返回到客户端,父/子socket都应通过socket_close($msgsock)函数来终止
    socket_close($msgSocket);
} while (true);

socket_close($sock);
//from https://blog.csdn.net/hguisu/article/details/7448528#t1